var async = require('async');
var https = require('https');
var weixinUtil = require('../../common/utils/weixinUtil');

function httpsRequest(options, callback) {   // only supports json objects, NO BUFFERS
    var getReq = https.request(options, function (response) {
        var dataStr = "";
        response.on('data', function (data) {
            dataStr += data.toString('utf8');
        });
        response.on('end', function () {
            callback(null, JSON.parse(dataStr));
        });
    });
    getReq.end();
    getReq.on('error', function (err) {
        callback(err, null);
    })
}

var wechatHost = "api.weixin.qq.com";

// weixin details from global config
var appId = wxAppId;
var appSecret = wxAppSecret;
//var appId = "wx8d557912df7e5589";
//var appSecret = "b6b3b7575eeea9ea6e8f1fa27d863180";

var nonceStr = "66xiaoqu";
var timestamp = weixinUtil.getTimestamp();
var access_token = "";
var jsapi_ticket = "";
var tokenRefreshTime = 7200/2; // in seconds

function accessTokenService(callback) {
    var options = {
        host: wechatHost,
        path: "/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}".format(appId, appSecret),
        method: 'GET'
    };
    httpsRequest(options, function (err, result) {
        if (!err && !('errmsg' in result)) {
            timestamp = weixinUtil.getTimestamp();
            access_token = result.access_token;
            //tokenRefreshTime = result.expires_in;
            logger.info("Latest access_token at {0}: {1}".format(timestamp, access_token));
        }
        callback(err, access_token);
    });
};

function jsapiTicketService(callback) {
    var ts = weixinUtil.getTimestamp();
    if (jsapi_ticket.length == 0 || ts >= (timestamp + tokenRefreshTime)) {
        accessTokenService(function () {
            var options = {
                host: wechatHost,
                path: "/cgi-bin/ticket/getticket?access_token={0}&type=jsapi".format(access_token),
                method: 'GET'
            };
            httpsRequest(options, function (err, result) {
                if (!err && result.errcode == 0) {
                    jsapi_ticket = result.ticket;
                    logger.info("Latest jsapi_ticket at {0}: {1}".format(ts, jsapi_ticket));
                }
                callback(err, jsapi_ticket);
            });
        })
    } else {
        callback(null, jsapi_ticket);
    }
};

exports.openIdService = function (code, callback) {
    var options = {
        host: wechatHost,
        path: "/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code".format(appId, appSecret, code),
        method: 'GET'
    };
    httpsRequest(options, callback);
};

exports.getWxConfigService = function (url, callback) {
    jsapiTicketService(function () {
        var input = {
            noncestr: nonceStr,
            jsapi_ticket: jsapi_ticket,
            timestamp: timestamp,
            url: url
        };
        var signature = weixinUtil.getSignature(input);
        var wxConfig = {
            appId: appId, // 必填，公众号的唯一标识
            timestamp: timestamp, // 必填，生成签名的时间戳
            nonceStr: nonceStr, // 必填，生成签名的随机串
            signature: signature // 必填，签名，见附录1
        };
        callback(null, JSON.stringify(wxConfig));
    })
};

exports.userProfileService = function (openId, callback) {
    var options = {
        host: wechatHost,
        path: "/cgi-bin/user/info?access_token={0}&openid={1}&lang=en_US".format(access_token, openId),
        method: 'GET'
    };
    var ts = weixinUtil.getTimestamp();
    if (access_token.length == 0 || ts >= (timestamp + tokenRefreshTime)) {
        accessTokenService(function () {
            options.path = "/cgi-bin/user/info?access_token={0}&openid={1}&lang=en_US".format(access_token, openId);
            httpsRequest(options, callback);
        })
    }else
        httpsRequest(options, callback);
};

exports.getSubscribedUsersService = function (query, callback) {
    var options = {
        host: wechatHost,
        path: "/cgi-bin/user/get?access_token={0}",
        method: 'GET'
    };
    if (query && query.next_openid){
        options.path += "&next_openid=" + query.next_openid;
    }
    var ts = weixinUtil.getTimestamp();
    if (access_token.length == 0 || ts >= (timestamp + tokenRefreshTime)) {
        accessTokenService(function () {
            options.path = options.path.format(access_token);
            httpsRequest(options, callback);
        })
    } else {
        options.path = options.path.format(access_token);
        httpsRequest(options, callback);
    }
};